package com.libui.navigatonbar

import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.text.SpannableString
import android.text.Spanned
import android.text.TextUtils
import android.text.style.AbsoluteSizeSpan
import android.util.AttributeSet
import android.util.TypedValue
import android.view.Gravity
import android.view.LayoutInflater
import android.widget.LinearLayout
import androidx.constraintlayout.widget.ConstraintLayout
import com.libui.IconFonts
import com.libui.R
import com.libui.TextViewEx
import com.libui.navigatonbar.menuview.TitleMenuView
import com.libui.utils.WindowUtils
import kotlin.math.max
import kotlin.properties.Delegates

class NavigationBar(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
    ConstraintLayout(context, attrs, defStyleAttr) {
    val backButton: TitleMenuView

    val titleView: TextViewEx

    private val leftMenusView: LinearLayout

    private val rightMenusView: LinearLayout

    var onMenuTap: OnMenuTap? = null

    constructor(context: Context) : this(context, null)

    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)

    init {
        LayoutInflater.from(context).inflate(R.layout.navigation_bar, this, true)

        val content = findViewById<ConstraintLayout>(R.id.navigation_bar_content)
        val statusBarHeight = WindowUtils.instance.getStatusBarPixelHeight(context)
        content.setPadding(0, statusBarHeight, 0, 0)
        content.layoutParams = LayoutParams(
            LayoutParams.MATCH_PARENT,
            resources.getDimensionPixelSize(R.dimen.navigation_bar_height) + statusBarHeight
        )

        val typedValue = TypedValue()
        context.theme.resolveAttribute(androidx.appcompat.R.attr.colorPrimary, typedValue, true)
        setBackgroundColor(typedValue.data)

        backButton = findViewById(R.id.back_button)
        val backButtonTitle = IconFonts.instance.dataSource?.iconNavigationBack
            ?: content.resources.getString(R.string.back)
        backButton.setMenuData(
            MenuData("back_button", null, backButtonTitle)
        ) {
            val activity = context as? Activity ?: return@setMenuData
            activity.finish()
        }

        titleView = findViewById(R.id.title_view)
        titleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16F)
        titleView.setTextColor(Color.WHITE)
        titleView.gravity = Gravity.CENTER
        titleView.ellipsize = TextUtils.TruncateAt.valueOf("END")

        leftMenusView = findViewById(R.id.left_menus_view)

        rightMenusView = findViewById(R.id.right_menus_view)
    }

    var title: String? = null
        private set

    var subTitle: String? = null
        private set

    var titleGravity: Int
        get() = titleView.gravity
        set(value) {
            titleView.gravity = value
        }

    var rightMenus: List<MenuData>? by Delegates.observable(null) { _, _, newValue ->
        rightMenusView.removeAllViews()

        newValue?.forEach {
            val titleMenuView = TitleMenuView(context)
            titleMenuView.setMenuData(it) { menuData ->
                onMenuTap?.let { it(menuData) }
            }

            val layoutParams =
                LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
            layoutParams.gravity = Gravity.CENTER_VERTICAL
            titleMenuView.layoutParams = layoutParams
            rightMenusView.addView(titleMenuView)
        }

        requestLayout()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val measureSpec =
            MeasureSpec.makeMeasureSpec(
                MeasureSpec.getSize(widthMeasureSpec),
                MeasureSpec.AT_MOST
            )
        leftMenusView.measure(measureSpec, heightMeasureSpec)
        rightMenusView.measure(measureSpec, heightMeasureSpec)

        if (titleGravity == Gravity.CENTER) {
            val menusViewWidth = max(leftMenusView.measuredWidth, rightMenusView.measuredWidth)
            leftMenusView.layoutParams.width = menusViewWidth
            rightMenusView.layoutParams.width = menusViewWidth
        } else {
            val margin = context.resources.getDimensionPixelSize(R.dimen.navigation_bar_margin)
            titleView.layoutParams.width = MeasureSpec.getSize(widthMeasureSpec) - margin * 4 -
                    leftMenusView.measuredWidth - rightMenusView.measuredWidth
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    }

    fun setTitle(title: String?, subTitle: String?) {
        this.title = title
        this.subTitle = subTitle

        if (subTitle != null) {
            titleView.setLines(2)

            val newTitle = title ?: ""
            val spannableString = SpannableString(newTitle + "\n" + subTitle)

            spannableString.setSpan(
                TitleSpan(titleView),
                0,
                newTitle.length,
                Spanned.SPAN_INCLUSIVE_EXCLUSIVE
            )

            spannableString.setSpan(
                AbsoluteSizeSpan(16, true),
                0,
                newTitle.length,
                Spanned.SPAN_INCLUSIVE_EXCLUSIVE
            )

            spannableString.setSpan(
                AbsoluteSizeSpan(14, true),
                newTitle.length,
                spannableString.length,
                Spanned.SPAN_INCLUSIVE_EXCLUSIVE
            )

            titleView.text = spannableString
        } else {
            titleView.setLines(2)

            titleView.text = title
        }
    }

    fun setTitle(title: String?) {
        setTitle(title, subTitle)
    }

    fun setSubTitle(subTitle: String?) {
        setTitle(title, subTitle)
    }
}